#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char const *argv[])
{
    char* shm_name = "unnamed_sem_shm";
    // 创建共享内存
    int fd = shm_open(shm_name, O_CREAT | O_RDWR, 0644);
    // 调整贡献内存大小
    ftruncate(fd, sizeof(sem_t));
    // 完成映射
    sem_t* sem = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    // 初始化信号量
    sem_init(sem, 1, 0);

    // 创建父子进程
    pid_t pid = fork();

    if(pid < 0)
    {
        perror("fork");
    }
    else if(pid == 0)
    {
        // 子进程
        sleep(1);
        printf("这是子进程\n");
        // 子进程释放信号量 sem + 1 唤醒父进程
        sem_post(sem);
    }
    else
    {
        // 父进程
        // 子进程睡眠一秒，保证父进程先执行
        // sem - 1 < 0 阻塞
        sem_wait(sem);
        printf("这是父进程\n");
        waitpid(pid, NULL, 0);

        // 回收资源
        if(sem_destroy(sem) == -1)
        {
            perror("sem_destroy");
        }
        if(shm_unlink(shm_name) == -1)
        {
            perror("shm_unlink");
        }
    }

    // 父子进程都需要关闭的文件描述符

    if(munmap(sem, sizeof(sem_t)) == -1)
    {
        perror("mumap");
    }
    if(close(fd) == -1)
    {
        perror("close");
    }


    return 0;
}
